package com.bf.electroplating.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bf.electroplating.login.UserContext;
import com.bf.electroplating.login.UserDetail;
import com.bf.electroplating.mapper.InspectionFeedbackMapper;
import com.bf.electroplating.mapper.InspectionTaskMapper;
import com.bf.electroplating.pojo.dto.inspection.InspectionFeedbackDTO;
import com.bf.electroplating.pojo.entity.*;
import com.bf.electroplating.pojo.enums.*;
import com.bf.electroplating.pojo.vo.inspection.InspectionFeedbackVO;
import com.bf.electroplating.service.*;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 15451
 * @description 针对表【inspection_feedback(巡检反馈表)】的数据库操作Service实现
 * @createDate 2025-06-16 09:09:25
 */
@Service
public class InspectionFeedbackServiceImpl extends ServiceImpl<InspectionFeedbackMapper, InspectionFeedback>
        implements InspectionFeedbackService {

    @Resource
    private PubAttachmentService attachmentService;
    @Resource
    private PubAttachmentRelService attachmentRelService;
    @Resource
    private InspectionTaskCompanyService inspectionTaskCompanyService;
    @Resource
    private InspectionTaskFacilityService inspectionTaskFacilityService;
    @Resource
    private InspectionTaskUserService inspectionTaskUserService;
    @Resource
    private ComCompanyService comCompanyService;
    @Resource
    private ComEnvironmentallyFacilityService comEnvironmentallyFacilityService;
    @Resource
    private InspectionTaskMapper inspectionTaskMapper;
    @Resource
    private ISysUserService sysUserService;

    @Override
    public Page<InspectionFeedbackVO> getFeedbackList(InspectionFeedbackDTO dto,Boolean isResult) {
        Page<InspectionFeedback> page = new Page<>(dto.getPageNum(), dto.getPageSize());
        LambdaQueryWrapper<InspectionFeedback> wrapper = new LambdaQueryWrapper<>();

        if (StringUtils.hasText(dto.getInspectionType())) {
            wrapper.eq(InspectionFeedback::getInspectionType, dto.getInspectionType());
        }
        if (StringUtils.hasText(dto.getInspectionStatus())) {
            wrapper.eq(InspectionFeedback::getInspectionStatus, dto.getInspectionStatus());
        }
        if (StringUtils.hasText(dto.getInspectionName())) {
            List<InspectionTask> inspectionTasks = inspectionTaskMapper.selectList(new LambdaQueryWrapper<InspectionTask>()
                    .like(InspectionTask::getInspectionName, dto.getInspectionName()));
            if (!CollectionUtils.isEmpty(inspectionTasks)){
                wrapper.in(InspectionFeedback::getTaskId, inspectionTasks.stream().map(InspectionTask::getId).toList());
            }
        }
        UserDetail user = UserContext.getUser();
        if (CollectionUtils.isEmpty(user.getParkFunctionIds())){
            List<InspectionTaskUser> taskUsers = inspectionTaskUserService.list(new LambdaQueryWrapper<InspectionTaskUser>().eq(InspectionTaskUser::getUserId, user.getId()));
            if (CollectionUtils.isEmpty(taskUsers)){
                return new Page<>();
            }else {
                wrapper.in(InspectionFeedback::getTaskId, taskUsers.stream().map(InspectionTaskUser::getTaskId).toList());
            }
        }
        if (isResult){
            wrapper.isNotNull(InspectionFeedback::getInspectionStatus);
        }

        Page<InspectionFeedback> feedbackPage = this.page(page, wrapper);
        Page<InspectionFeedbackVO> voPage = new Page<>();
        BeanUtils.copyProperties(feedbackPage, voPage, "records");
        List<InspectionFeedbackVO> voList = feedbackPage.getRecords().stream().map(feedback -> {
            InspectionTask task =  inspectionTaskMapper.selectById(feedback.getTaskId());
            InspectionFeedbackVO vo = new InspectionFeedbackVO();
            BeanUtils.copyProperties(feedback, vo);
            vo.setInspectionTime(getDateStr(feedback.getInspectionTime()));
            vo.setInspectionStatus(InspectionStatusEnum.getDesc(feedback.getInspectionStatus()));
            vo.setInspectionName(task.getInspectionName());
            vo.setInspectionContent(task.getInspectionContent());
            vo.setInspectionFrequency(InspectionFrequencyEnum.getDesc(task.getInspectionFrequency()));
            vo.setInspectionDeadlineList(getDateStr(task.getStartTime()) + " ~ " + getDateStr(task.getEndTime()));
            if (InspectionTypeEnum.COMPANY.getCode().equals(feedback.getInspectionType())) {
                InspectionTaskCompany taskCompanies = inspectionTaskCompanyService.getOne(new LambdaQueryWrapper<InspectionTaskCompany>()
                        .eq(InspectionTaskCompany::getTaskId, feedback.getTaskId())
                        .eq(InspectionTaskCompany::getCompanyId, feedback.getInspectionPoint()));
                ComCompany comCompany = comCompanyService.getById(taskCompanies.getCompanyId());
                vo.setInspectionPoint(comCompany.getCompanyName());
            } else {
                InspectionTaskFacility taskFacilities = inspectionTaskFacilityService.getOne(new LambdaQueryWrapper<InspectionTaskFacility>()
                        .eq(InspectionTaskFacility::getTaskId, feedback.getTaskId())
                        .eq(InspectionTaskFacility::getFacilityId, feedback.getInspectionPoint()));
                ComEnvironmentallyFacility facility = comEnvironmentallyFacilityService.getById(taskFacilities.getFacilityId());
                vo.setInspectionPoint(facility.getEnvironmentalFacilityName());
            }
            if (CollectionUtils.isEmpty(user.getParkFunctionIds())){
                vo.setUserList(user.getUserName());
            }else {
                List<InspectionTaskUser> taskUsers = inspectionTaskUserService.list(new LambdaQueryWrapper<InspectionTaskUser>().eq(InspectionTaskUser::getTaskId, feedback.getTaskId()));
                vo.setUserList(taskUsers.stream().map(InspectionTaskUser::getUserId).map(userId ->{
                    SysUser sysUser=sysUserService.getById(userId);
                    if (sysUser!=null) {
                        return sysUser.getUserName();
                    }else {
                        return "";
                    }
                }
              ).collect(Collectors.joining("、")));
            }
            // 获取照片
            vo.setPhotoIds(attachmentService.getWholeFile(feedback.getId(), AttModuleEnums.INSPECTION_PHOTO.getCode()));
            // 获取附件
            vo.setAttachmentIds(attachmentService.getWholeFile(feedback.getId(), AttModuleEnums.INSPECTION_ATTACHMENT.getCode()));
            vo.setInspectionType(InspectionTypeEnum.getDesc(feedback.getInspectionType()));
            return vo;
        }).collect(Collectors.toList());

        voPage.setRecords(voList);
        return voPage;
    }

    private String getDateStr(Date date) {
        if (date == null){
            return null;
        }
        LocalDate localDate = date.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDate();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return formatter.format(localDate);
    }

    @Override
    public InspectionFeedbackVO getFeedbackById(String id) {
        InspectionFeedback feedback = this.getById(id);
        if (feedback == null) {
            return null;
        }
        InspectionFeedbackVO vo = new InspectionFeedbackVO();
        BeanUtils.copyProperties(feedback, vo);
        InspectionTask task =  inspectionTaskMapper.selectById(feedback.getTaskId());
        vo.setInspectionName(task.getInspectionName());
        vo.setInspectionContent(task.getInspectionContent());
        vo.setInspectionFrequency(task.getInspectionFrequency());
        vo.setInspectionPersonnel(inspectionTaskUserService.list(new LambdaQueryWrapper<InspectionTaskUser>().eq(InspectionTaskUser::getTaskId, task.getId())).stream().map(InspectionTaskUser::getUserId).toList());
        List<String> dateList=new ArrayList<>();
        dateList.add(getDateStr(task.getStartTime()));
        dateList.add(getDateStr(task.getEndTime()));
        vo.setInspectionDeadline(dateList);
        vo.setInspectionTime(getDateStr(feedback.getInspectionTime()));
        if (InspectionTypeEnum.COMPANY.getCode().equals(feedback.getInspectionType())) {
            InspectionTaskCompany taskCompanies = inspectionTaskCompanyService.getOne(new LambdaQueryWrapper<InspectionTaskCompany>()
                    .eq(InspectionTaskCompany::getTaskId, feedback.getTaskId())
                    .eq(InspectionTaskCompany::getCompanyId, feedback.getInspectionPoint()));
            ComCompany comCompany = comCompanyService.getById(taskCompanies.getCompanyId());
            vo.setInspectionPoint(comCompany.getCompanyName());
        } else {
            InspectionTaskFacility taskFacilities = inspectionTaskFacilityService.getOne(new LambdaQueryWrapper<InspectionTaskFacility>()
                    .eq(InspectionTaskFacility::getTaskId, feedback.getTaskId())
                    .eq(InspectionTaskFacility::getFacilityId, feedback.getInspectionPoint()));
            ComEnvironmentallyFacility facility = comEnvironmentallyFacilityService.getById(taskFacilities.getFacilityId());
            vo.setInspectionPoint(facility.getEnvironmentalFacilityName());
        }
        // 获取照片
        vo.setPhotoIds(attachmentService.getWholeFile(feedback.getId(), AttModuleEnums.INSPECTION_PHOTO.getCode()));
        // 获取附件
        vo.setAttachmentIds(attachmentService.getWholeFile(feedback.getId(), AttModuleEnums.INSPECTION_ATTACHMENT.getCode()));
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateFeedback(InspectionFeedbackVO vo) {
        InspectionFeedback feedback = new InspectionFeedback();
        BeanUtils.copyProperties(vo, feedback);
        feedback.setInspectionPoint(null);
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            feedback.setInspectionTime(sdf.parse(vo.getInspectionTime()));
        } catch (ParseException e) {
            log.error("日期解析失败：" + e.getMessage());
        }
        boolean result = this.updateById(feedback);
        if (result) {
            // 更新照片关联
            attachmentRelService.remove(new LambdaQueryWrapper<PubAttachmentRel>()
                    .eq(PubAttachmentRel::getStorePath, AttModuleEnums.INSPECTION_PHOTO.getCode())
                    .eq(PubAttachmentRel::getRelationId, feedback.getId()));
            if (vo.getPhotoIds() != null && !vo.getPhotoIds().isEmpty()) {
                attachmentService.saveWholeAttachmentRel(vo.getPhotoIds(), feedback.getId(), AttModuleEnums.INSPECTION_PHOTO.getCode());
            }
            // 更新附件关联
            attachmentRelService.remove(new LambdaQueryWrapper<PubAttachmentRel>()
                    .eq(PubAttachmentRel::getStorePath, AttModuleEnums.INSPECTION_ATTACHMENT.getCode())
                    .eq(PubAttachmentRel::getRelationId, feedback.getId()));
            if (vo.getAttachmentIds() != null && !vo.getAttachmentIds().isEmpty()) {
                attachmentService.saveWholeAttachmentRel(vo.getAttachmentIds(), feedback.getId(), AttModuleEnums.INSPECTION_ATTACHMENT.getCode());
            }
        }
        List<InspectionFeedback> feedbacks = list(new LambdaQueryWrapper<InspectionFeedback>().eq(InspectionFeedback::getTaskId, vo.getTaskId()));
        InspectionTask task = inspectionTaskMapper.selectById(vo.getTaskId());
        // 变更任务状态
        if (feedbacks.stream().noneMatch(i -> i.getInspectionStatus()==null)){
            // 判断是否超时
            if (isNotSameDay(task.getEndTime(),new Date()) && task.getEndTime().before(new Date())){
                task.setStatus(InspectionTaskStatusEnum.YET_OVER.getCode());
            }else {
                task.setStatus(InspectionTaskStatusEnum.YET.getCode());
            }
        }else {
            if (isNotSameDay(task.getEndTime(),new Date()) && task.getEndTime().before(new Date())){
                task.setStatus(InspectionTaskStatusEnum.ING_OVER.getCode());
            }else {
                task.setStatus(InspectionTaskStatusEnum.ING.getCode());
            }
        }
        inspectionTaskMapper.updateById(task);
        return result;
    }

    public boolean isNotSameDay(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        cal1.setTime(date1);
        cal2.setTime(date2);

        return cal1.get(Calendar.YEAR) != cal2.get(Calendar.YEAR) ||
                cal1.get(Calendar.MONTH) != cal2.get(Calendar.MONTH) ||
                cal1.get(Calendar.DAY_OF_MONTH) != cal2.get(Calendar.DAY_OF_MONTH);
    }

}




